package com.gitee.wsl.common.chart.sample.pie

import android.graphics.Canvas
import com.gitee.wsl.android.ext.base.getForegroundColorForBackgroundColor
import com.gitee.wsl.android.ext.math.calcArcEndPointXY
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.sample.pie.model.PieData
import com.gitee.wsl.common.chart.model.PlotArcLabelInfo
import com.gitee.wsl.ext.base.ColorExt
import com.gitee.wsl.math.Math
import com.gitee.wsl.jvm.math.add
import com.gitee.wsl.jvm.math.div
import com.gitee.wsl.jvm.math.sub
import com.gitee.wsl.math.getSliceAngle


class PieChart3D : PieChart() {
    
    //渲染层数
    var render3DLevel = 15

    override fun getType(): ChartEnum.ChartType {
        return ChartEnum.ChartType.PIE3D
    }

    private fun draw3D(
        canvas: Canvas,
        initOffsetAngle: Float,
        chartDataSource: List<PieData>,
        cirX: Float, cirY: Float, radius: Float
    ): Boolean {
        var offsetAngle = initOffsetAngle
        var currentAngle = 0.0f
        var newRadius = 0.0f
        var size = 0
        for (i in 0 until render3DLevel) {
            //canvas.save(Canvas.MATRIX_SAVE_FLAG);
            canvas.save()
            canvas.translate(0f, (render3DLevel - i).toFloat())
            size = chartDataSource.size
            for (j in 0 until size) {
                val cData = chartDataSource[j]
                //currentAngle = cData.getSliceAngle();		
                currentAngle = Math.getSliceAngle(totalAngle, cData.percentage)
                if (!validateAngle(currentAngle)) continue
                arcPaint.setColor(cData.sliceColor)
                if (cData.isSelected) //指定突出哪个块
                {
                    //偏移圆心点位置(默认偏移半径的1/10)
                    newRadius = Math.div(radius, selectedOffset)
                    //计算百分比标签
                    val point = Math.calcArcEndPointXY(
                        cirX, cirY, newRadius,
                        Math.add(offsetAngle, Math.div(currentAngle, 2f))
                    )
                    initRectF(
                        Math.sub(point.x, radius), Math.sub(point.y, radius),
                        Math.add(point.x, radius), Math.add(point.y, radius)
                    )
                    canvas.drawArc(rectF, offsetAngle, currentAngle, true, arcPaint)
                } else {
                    //确定饼图范围       
                    initRectF(
                        Math.sub(cirX, radius), Math.sub(cirY, radius),
                        Math.add(cirX, radius), Math.add(cirY, radius)
                    )
                    canvas.drawArc(rectF, offsetAngle, currentAngle, true, arcPaint)
                }
                //下次的起始角度  
                offsetAngle = Math.add(offsetAngle, currentAngle)
            }
            canvas.restore()
            offsetAngle = initOffsetAngle
        }
        return true
    }

    private fun drawFlatArcAndLegend(
        canvas: Canvas,
        initOffsetAngle: Float,
        chartDataSource: List<PieData>,
        cirX: Float, cirY: Float, radius: Float
    ): Boolean {
        var offsetAngle = initOffsetAngle
        var currentAngle = 0.0f
        var newRadius = 0.0f
        val size = chartDataSource.size
        lstLabels.clear()
        val left: Float = Math.sub(cirX, radius)
        val top: Float = Math.sub(cirY, radius)
        val right: Float = Math.add(cirX, radius)
        val bottom: Float = Math.add(cirY, radius)
        for (j in 0 until size) {
            val cData = chartDataSource[j] ?: continue
            //currentAngle = cData.getSliceAngle();
            currentAngle = Math.getSliceAngle(totalAngle, cData.percentage)
            if (!validateAngle(currentAngle)) continue

            arcPaint.color = ColorExt.getForegroundColorForBackgroundColor(cData.sliceColor)

            if (cData.isSelected) //指定突出哪个块
            {
                //偏移圆心点位置(默认偏移半径的1/10)
                newRadius = Math.div(radius, selectedOffset)
                //计算百分比标签
                val point = Math.calcArcEndPointXY(
                    cirX, cirY, newRadius, Math.add(offsetAngle, Math.div(currentAngle, 2f))
                )
                initRectF(
                    Math.sub(point.x, radius), Math.sub(point.y, radius),
                    Math.add(point.x, radius), Math.add(point.y, radius)
                )
                canvas.drawArc(rectF, offsetAngle, currentAngle, true, arcPaint)
                lstLabels.add(
                    PlotArcLabelInfo(
                        j,
                        point.x,
                        point.y,
                        radius,
                        offsetAngle,
                        currentAngle
                    )
                )
            } else {
                //确定饼图范围       
                initRectF(left, top, right, bottom)
                canvas.drawArc(rectF, offsetAngle, currentAngle, true, arcPaint)
                lstLabels.add(PlotArcLabelInfo(j, cirX, cirY, radius, offsetAngle, currentAngle))
            }

            //保存角度
            saveArcRecord(j, cirX + translateXY[0], cirY + translateXY[1],
                radius, offsetAngle, currentAngle,
                selectedOffset, this.offsetAngle
            )

            //下次的起始角度  
            offsetAngle = Math.add(offsetAngle, currentAngle)
        }

        //绘制Label
        drawLabels(canvas)

        //图例
        //plotLegend.renderPieKey(canvas, chartDataSource)
        //renderLegend(canvas, chartDataSource)
        return true
    }


    override fun drawPlot(canvas: Canvas): Boolean {
        //数据源
        /*val chartDataSource: List<PieData> = this.getDataSource()
        if (null == chartDataSource) {
            Log.e(PieChart3D.TAG, "数据源为空.")
            return false
        }*/

        //计算中心点坐标
        val cirX: Float = bodyViewport.centerX
        val cirY: Float = bodyViewport.centerY
        val radius: Float = radius
        return if (draw3D(canvas, offsetAngle, dataSet, cirX, cirY, radius)) {
            drawFlatArcAndLegend(
                canvas, offsetAngle, dataSet,
                cirX, cirY, radius
            )
        } else {
            false
        }
    }
}